// RAP [rh] KeyBindingService disabed, since the implemented interface is not supported
///*******************************************************************************
// * Copyright (c) 2000, 2009 IBM Corporation and others.
// * All rights reserved. This program and the accompanying materials
// * are made available under the terms of the Eclipse Public License v1.0
// * which accompanies this distribution, and is available at
// * http://www.eclipse.org/legal/epl-v10.html
// *
// * Contributors:
// *     IBM Corporation - initial API and implementation
// *******************************************************************************/
//package org.eclipse.ui.internal;
//
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.Collections;
//import java.util.HashMap;
//import java.util.HashSet;
//import java.util.Iterator;
//import java.util.List;
//import java.util.Map;
//import java.util.Set;
//
//import org.eclipse.jface.action.IAction;
//import org.eclipse.ui.IKeyBindingService;
//import org.eclipse.ui.INestableKeyBindingService;
//import org.eclipse.ui.IWorkbenchPartSite;
//import org.eclipse.ui.IWorkbenchSite;
//import org.eclipse.ui.PlatformUI;
//import org.eclipse.ui.commands.ActionHandler;
//import org.eclipse.ui.commands.HandlerSubmission;
//import org.eclipse.ui.commands.IHandler;
//import org.eclipse.ui.commands.Priority;
//import org.eclipse.ui.contexts.EnabledSubmission;
//import org.eclipse.ui.internal.actions.CommandAction;
//import org.eclipse.ui.internal.handlers.CommandLegacyActionWrapper;
//
///**
// * This service provides a nestable implementation of a key binding service.
// * This class is provided for backwards compatibility only, and might be removed
// * in the future. All of the functionality is the class can be duplicated by
// * using the commands and contexts API.
// * 
// * @since 2.0
// */
//public final class KeyBindingService implements INestableKeyBindingService {
//
//    /**
//     * The currently active nested service, if any. If there are no nested
//     * services or none of them are active, then this value is <code>null</code>.
//     */
//    private IKeyBindingService activeService = null;
//
//    /**
//     * Whether this key binding service has been disposed.  A disposed key
//     * binding service should not be used again.
//     */
//    private boolean disposed;
//
//    /**
//     * The set of context identifiers enabled in this key binding service (not
//     * counting any nested services). This set may be empty, but it is never
//     * <code>null</code>.
//     */
//    private Set enabledContextIds = Collections.EMPTY_SET;
//
//    /**
//     * The list of context submissions indicating the enabled state of the
//     * context. This does not include those from nested services. This list may
//     * be empty, but it is never <code>null</code>.
//     */
//    private List enabledSubmissions = new ArrayList();
//
//    /**
//     * The map of handler submissions, sorted by command identifiers. This does
//     * not include those from nested services. This map may be empty, but it is
//     * never <code>null</code>.
//     */
//    private Map handlerSubmissionsByCommandId = new HashMap();
//
//    /**
//     * The context submissions from the currently active nested service. This
//     * value is <code>null</code> if there is no currently active nested
//     * service.
//     */
//    private List nestedEnabledSubmissions = null;
//
//    /**
//     * The handler submissions from the currently active nested service. This
//     * value is <code>null</code> if there is no currently active handler
//     * service.
//     */
//    private List nestedHandlerSubmissions = null;
//
//    /**
//     * The map of workbench part sites to nested key binding services. This map
//     * may be empty, but is never <code>null</code>.
//     */
//    private final Map nestedServices = new HashMap();
//
//    /**
//     * The parent for this key binding service; <code>null</code> if there is
//     * no parent. If there is a parent, then this means that it should not do a
//     * "live" update of its contexts or handlers, but should make a call to the
//     * parent instead.
//     */
//    private final KeyBindingService parent;
//
//    /**
//     * The site within the workbench at which this service is provided. This
//     * value should not be <code>null</code>.
//     */
//    private IWorkbenchPartSite workbenchPartSite;
//
//    /**
//     * Constructs a new instance of <code>KeyBindingService</code> on a given
//     * workbench site. This instance is not nested.
//     * 
//     * @param workbenchPartSite
//     *            The site for which this service will be responsible; should
//     *            not be <code>null</code>.
//     */
//    public KeyBindingService(IWorkbenchPartSite workbenchPartSite) {
//        this(workbenchPartSite, null);
//    }
//
//    /**
//     * Constructs a new instance of <code>KeyBindingService</code> on a given
//     * workbench site.
//     * 
//     * @param workbenchPartSite
//     *            The site for which this service will be responsible; should
//     *            not be <code>null</code>.
//     * @param parent
//     *            The parent key binding service, if any; <code>null</code> if
//     *            none.
//     */
//    KeyBindingService(IWorkbenchPartSite workbenchPartSite,
//            KeyBindingService parent) {
//        this.workbenchPartSite = workbenchPartSite;
//        this.parent = parent;
//    }
//
//    /*
//     * (non-Javadoc)
//     * 
//     * @see org.eclipse.ui.INestableKeyBindingService#activateKeyBindingService(org.eclipse.ui.IWorkbenchSite)
//     */
//    public boolean activateKeyBindingService(IWorkbenchSite nestedSite) {
//        if (disposed) {
//			return false;
//		}
//
//        // Check if we should do a deactivation.
//        if (nestedSite == null) {
//            // We should do a deactivation, if there is one active.
//            if (activeService == null) {
//                // There is no active service. Do no work.
//                return false;
//            }
//            // Deactivate the currently active nested service.
//            deactivateNestedService();
//            return true;
//        }
//
//        // Attempt to activate a service.
//        final IKeyBindingService service = (IKeyBindingService) nestedServices
//                .get(nestedSite);
//        
//        if (service == activeService) {
//            // The service is already active, or already null
//            return false;
//        }
//
//        deactivateNestedService();
//        if (service!=null) {
//        	activateNestedService(service);
//        }
//        return true;
//    }
//
//    /**
//     * Activates the given service without worrying about the currently active
//     * service. This goes through the work of adding all of the nested context
//     * ids as enabled submissions.
//     * 
//     * @param service
//     *            The service to become active; if <code>null</code>, then
//     *            the reference to the active service is set to
//     *            <code>null</code> but nothing else happens.
//     */
//    private final void activateNestedService(final IKeyBindingService service) {
//        if (disposed) {
//			return;
//		}
//
//        /*
//         * If I have a parent, and I'm the active service, then deactivate so
//         * that I can make changes.
//         */
//        boolean active = false;
//        boolean haveParent = (parent != null);
//        if (haveParent) {
//            active = (parent.activeService == this);
//            if (active) {
//                parent.deactivateNestedService();
//            }
//        }
//
//        // Update the active service.
//        activeService = service;
//
//        // Check to see that the service isn't null.
//        if (service == null) {
//            return;
//        }
//
//        if (haveParent) {
//            if (active) {
//                parent.activateNestedService(this);
//            }
//
//        } else if (activeService instanceof KeyBindingService) {
//            // I have no parent, so I can make the changes myself.
//            final KeyBindingService nestedService = (KeyBindingService) activeService;
//
//            // Update the contexts.
//            nestedEnabledSubmissions = nestedService.getEnabledSubmissions();
//            normalizeSites(nestedEnabledSubmissions);
//            PlatformUI.getWorkbench().getContextSupport().addEnabledSubmissions(
//                    nestedEnabledSubmissions);
//
//            // Update the handlers.
//            nestedHandlerSubmissions = nestedService.getHandlerSubmissions();
//            normalizeSites(nestedHandlerSubmissions);
//            PlatformUI.getWorkbench().getCommandSupport().addHandlerSubmissions(
//                    nestedHandlerSubmissions);
//        }
//    }
//
//    /**
//     * Deactives the currently active service. This nulls out the reference, and
//     * removes all the enabled submissions for the nested service.
//     */
//    private final void deactivateNestedService() {
//        if (disposed) {
//			return;
//		}
//
//        // Don't do anything if there is no active service.
//        if (activeService == null) {
//            return;
//        }
//
//        // Check to see if there is a parent.
//        boolean active = false;
//        if (parent != null) {
//            // Check if I'm the active service.
//            if (parent.activeService == this) {
//                active = true;
//                // Deactivate myself so I can make changes.
//                parent.deactivateNestedService();
//            }
//
//        } else if (activeService instanceof KeyBindingService) {
//            // Remove all the nested context ids.
//        	PlatformUI.getWorkbench().getContextSupport()
//                    .removeEnabledSubmissions(nestedEnabledSubmissions);
//
//            /*
//             * Remove all of the nested handler submissions. The handlers here
//             * weren't created by this instance (but by the nest instance), and
//             * hence can't be disposed here.
//             */
//        	PlatformUI.getWorkbench().getCommandSupport()
//                    .removeHandlerSubmissions(nestedHandlerSubmissions);
//
//        }
//
//        // Clear our reference to the active service.
//        activeService = null;
//
//        // If necessary, let my parent know that changes have occurred.
//        if (active) {
//            parent.activateNestedService(this);
//        }
//    }
//
//    /**
//     * Disposes this key binding service. This clears out all of the submissions
//     * held by this service, and its nested services.
//     */
//    public void dispose() {
//        if (!disposed) {
//            deactivateNestedService();
//            disposed = true;
//
//            PlatformUI.getWorkbench()
//                    .getContextSupport()
//                    .removeEnabledSubmissions(new ArrayList(enabledSubmissions));
//            enabledSubmissions.clear();
//
//            /*
//             * Each removed handler submission, must dispose its corresponding
//             * handler -- as these handlers only exist inside of this class.
//             */
//            final List submissions = new ArrayList(
//                    handlerSubmissionsByCommandId.values());
//            final Iterator submissionItr = submissions.iterator();
//            while (submissionItr.hasNext()) {
//                ((HandlerSubmission) submissionItr.next()).getHandler()
//                        .dispose();
//            }
//            PlatformUI.getWorkbench().getCommandSupport()
//                    .removeHandlerSubmissions(submissions);
//            handlerSubmissionsByCommandId.clear();
//
//            for (Iterator iterator = nestedServices.values().iterator(); iterator
//                    .hasNext();) {
//                KeyBindingService keyBindingService = (KeyBindingService) iterator
//                        .next();
//                keyBindingService.dispose();
//            }
//
//            nestedEnabledSubmissions = null;
//            nestedHandlerSubmissions = null;
//            nestedServices.clear();
//        }
//    }
//
//    /**
//     * Gets a copy of all the enabled submissions in the nesting chain.
//     * 
//     * @return All of the nested enabled submissions -- including the ones from
//     *         this service. This list may be empty, but is never
//     *         <code>null</code>.
//     */
//    private final List getEnabledSubmissions() {
//        if (disposed) {
//			return null;
//		}
//
//        final List submissions = new ArrayList(enabledSubmissions);
//        if (activeService instanceof KeyBindingService) {
//            final KeyBindingService nestedService = (KeyBindingService) activeService;
//            submissions.addAll(nestedService.getEnabledSubmissions());
//        }
//        return submissions;
//    }
//
//    /**
//     * Gets a copy of all the handler submissions in the nesting chain.
//     * 
//     * @return All of the nested handler submissions -- including the ones from
//     *         this service. This list may be empty, but is never
//     *         <code>null</code>.
//     */
//    private final List getHandlerSubmissions() {
//        if (disposed) {
//			return null;
//		}
//
//        final List submissions = new ArrayList(handlerSubmissionsByCommandId
//                .values());
//        if (activeService instanceof KeyBindingService) {
//            final KeyBindingService nestedService = (KeyBindingService) activeService;
//            submissions.addAll(nestedService.getHandlerSubmissions());
//        }
//        return submissions;
//    }
//
//    /*
//     * (non-Javadoc)
//     * 
//     * @see org.eclipse.ui.INestableKeyBindingService#getKeyBindingService(org.eclipse.ui.IWorkbenchSite)
//     */
//    public IKeyBindingService getKeyBindingService(IWorkbenchSite nestedSite) {
//        if (disposed) {
//			return null;
//		}
//
//        if (nestedSite == null) {
//            return null;
//        }
//
//        IKeyBindingService service = (IKeyBindingService) nestedServices
//                .get(nestedSite);
//        if (service == null) {
//            // TODO the INestedKeyBindingService API should be based on
//            // IWorkbenchPartSite..
//            if (nestedSite instanceof IWorkbenchPartSite) {
//				service = new KeyBindingService(
//                        (IWorkbenchPartSite) nestedSite, this);
//			} else {
//				service = new KeyBindingService(null, this);
//			}
//
//            nestedServices.put(nestedSite, service);
//        }
//
//        return service;
//    }
//
//    public String[] getScopes() {
//        if (disposed) {
//			return null;
//		}
//
//        // Get the nested scopes, if any.
//        final String[] nestedScopes;
//        if (activeService == null) {
//            nestedScopes = null;
//        } else {
//            nestedScopes = activeService.getScopes();
//        }
//
//        // Build the list of active scopes
//        final Set activeScopes = new HashSet();
//        activeScopes.addAll(enabledContextIds);
//        if (nestedScopes != null) {
//            for (int i = 0; i < nestedScopes.length; i++) {
//                activeScopes.add(nestedScopes[i]);
//            }
//        }
//
//        return (String[]) activeScopes.toArray(new String[activeScopes.size()]);
//    }
//
//    /**
//     * Replaces the active workbench site with this service's active workbench
//     * site. This ensures that the context manager will recognize the context as
//     * active. Note: this method modifies the list in place; it is
//     * <em>destructive</em>.
//     * 
//     * @param submissionsToModify
//     *            The submissions list to modify; must not be <code>null</code>,
//     *            but may be empty.
//     */
//    private final void normalizeSites(final List submissionsToModify) {
//        if (disposed) {
//			return;
//		}
//
//        final int size = submissionsToModify.size();
//        for (int i = 0; i < size; i++) {
//            final Object submission = submissionsToModify.get(i);
//            final Object replacementSubmission;
//
//            if (submission instanceof EnabledSubmission) {
//                final EnabledSubmission enabledSubmission = (EnabledSubmission) submission;
//                if (!workbenchPartSite.equals(enabledSubmission
//                        .getActiveWorkbenchPartSite())) {
//                    replacementSubmission = new EnabledSubmission(null,
//                            enabledSubmission.getActiveShell(),
//                            workbenchPartSite, enabledSubmission.getContextId());
//                } else {
//                    replacementSubmission = enabledSubmission;
//                }
//
//            } else if (submission instanceof HandlerSubmission) {
//                final HandlerSubmission handlerSubmission = (HandlerSubmission) submission;
//                if (!workbenchPartSite.equals(handlerSubmission
//                        .getActiveWorkbenchPartSite())) {
//                    replacementSubmission = new HandlerSubmission(null,
//                            handlerSubmission.getActiveShell(),
//                            workbenchPartSite,
//                            handlerSubmission.getCommandId(), handlerSubmission
//                                    .getHandler(), handlerSubmission
//                                    .getPriority());
//                } else {
//                    replacementSubmission = handlerSubmission;
//                }
//
//            } else {
//                replacementSubmission = submission;
//            }
//
//            submissionsToModify.set(i, replacementSubmission);
//        }
//
//    }
//
//    public void registerAction(IAction action) {
//        if (disposed) {
//			return;
//		}
//        
//        if (action instanceof CommandLegacyActionWrapper) {
//        	// this is a registration of a fake action for an already
//			// registered handler
//			WorkbenchPlugin
//					.log("Cannot register a CommandLegacyActionWrapper back into the system"); //$NON-NLS-1$
//			return;
//        }
//        
//        if (action instanceof CommandAction) {
//			// we unfortunately had to allow these out into the wild, but they
//			// still must not feed back into the system
//			return;
//        }
//
//        unregisterAction(action);
//        String commandId = action.getActionDefinitionId();
//        if (commandId != null) {
//            /*
//             * If I have a parent and I'm active, de-activate myself while
//             * making changes.
//             */
//            boolean active = false;
//            if ((parent != null) && (parent.activeService == this)) {
//                active = true;
//                parent.deactivateNestedService();
//            }
//
//            // Create the new submission
//            IHandler handler = new ActionHandler(action);
//            HandlerSubmission handlerSubmission = new HandlerSubmission(null,
//                    workbenchPartSite.getShell(), workbenchPartSite, commandId,
//                    handler, Priority.MEDIUM);
//            handlerSubmissionsByCommandId.put(commandId, handlerSubmission);
//
//            // Either submit the new handler myself, or simply re-activate.
//            if (parent != null) {
//                if (active) {
//                    parent.activateNestedService(this);
//                }
//            } else {
//            	PlatformUI.getWorkbench().getCommandSupport()
//                        .addHandlerSubmission(handlerSubmission);
//            }
//        }
//    }
//
//    /*
//     * (non-Javadoc)
//     * 
//     * @see org.eclipse.ui.INestableKeyBindingService#removeKeyBindingService(org.eclipse.ui.IWorkbenchSite)
//     */
//    public boolean removeKeyBindingService(IWorkbenchSite nestedSite) {
//        if (disposed) {
//			return false;
//		}
//
//        final IKeyBindingService service = (IKeyBindingService) nestedServices
//                .remove(nestedSite);
//        if (service == null) {
//            return false;
//        }
//
//        if (service.equals(activeService)) {
//            deactivateNestedService();
//        }
//
//        return true;
//    }
//
//    public void setScopes(String[] scopes) {
//        if (disposed) {
//			return;
//		}
//
//        // Either deactivate myself, or remove the previous submissions myself.
//        boolean active = false;
//        if ((parent != null) && (parent.activeService == this)) {
//            active = true;
//            parent.deactivateNestedService();
//        } else {
//        	PlatformUI.getWorkbench().getContextSupport()
//                    .removeEnabledSubmissions(enabledSubmissions);
//        }
//        enabledSubmissions.clear();
//
//        // Determine the new list of submissions.
//        enabledContextIds = new HashSet(Arrays.asList(scopes));
//        for (Iterator iterator = enabledContextIds.iterator(); iterator
//                .hasNext();) {
//            String contextId = (String) iterator.next();
//            enabledSubmissions.add(new EnabledSubmission(null, null,
//                    workbenchPartSite, contextId));
//        }
//
//        // Submit the new contexts myself, or simply re-active myself.
//        if (parent != null) {
//            if (active) {
//                parent.activateNestedService(this);
//            }
//        } else {
//        	PlatformUI.getWorkbench().getContextSupport().addEnabledSubmissions(
//                    enabledSubmissions);
//        }
//    }
//
//    public void unregisterAction(IAction action) {
//        if (disposed) {
//			return;
//		}
//        
//        if (action instanceof CommandLegacyActionWrapper) {
//        	// this is a registration of a fake action for an already
//			// registered handler
//			WorkbenchPlugin
//					.log("Cannot unregister a CommandLegacyActionWrapper out of the system"); //$NON-NLS-1$
//			return;
//        }
//
//        String commandId = action.getActionDefinitionId();
//
//        if (commandId != null) {
//            // Deactivate this service while making changes.
//            boolean active = false;
//            if ((parent != null) && (parent.activeService == this)) {
//                active = true;
//                parent.deactivateNestedService();
//            }
//
//            // Remove the current submission, if any.
//            HandlerSubmission handlerSubmission = (HandlerSubmission) handlerSubmissionsByCommandId
//                    .remove(commandId);
//
//            /*
//             * Either activate this service again, or remove the submission
//             * myself.
//             */
//            if (parent != null) {
//                if (active) {
//                    parent.activateNestedService(this);
//                }
//            } else {
//            	if (handlerSubmission != null) {
//            		PlatformUI.getWorkbench().getCommandSupport()
//                            .removeHandlerSubmission(handlerSubmission);
//                    handlerSubmission.getHandler().dispose();
//                }
//            }
//        }
//    }
//}
